#ifndef SC_STRBUF_H
#define SC_STRBUF_H

/*
自定义字符串缓冲功能
*/

#include "common.h"

#include <stdbool.h>
#include <stddef.h>
#include <string.h>

/* 本项目自定义的字符串缓冲 */
struct sc_strbuf {
    char *s;
    size_t len;
    size_t cap;
};

/**
 * Initialize the string buffer，用指定的长度初始化 sc_strbuf 结构。
 *
 * `buf->s` must be manually freed by the caller.
 * 
 * @param buf 自定义字符串缓冲区
 * @param init_cap 缓存区长度
 * @return 初始化成功返回true，否则返回false
 */
bool
sc_strbuf_init(struct sc_strbuf *buf, size_t init_cap);

/**
 * Append a string 添加一个字符串到缓冲区
 * Append `len` characters from `s` to the buffer.
 * @param buf 字符串添加到此缓冲区中
 * @param s 待添加的字符串
 * @param len 待添加的长度
 * @return 添加成功返回true
 */
bool
sc_strbuf_append(struct sc_strbuf *buf, const char *s, size_t len);

/**
 * Append a char 添加一个字符到字符串缓冲区中。
 *
 * Append a single character to the buffer.
 * @param buf 自定义字符串缓冲区
 * @param c 单个字符
 * @return 成功返回true，否则返回false
 */
bool
sc_strbuf_append_char(struct sc_strbuf *buf, const char c);

/**
 * Append a char `n` times
 *
 * Append the same characters `n` times to the buffer.
 */
bool
sc_strbuf_append_n(struct sc_strbuf *buf, const char c, size_t n);

/**
 * Append a NUL-terminated string. 添加一个/0结尾的字符串到缓冲区
 * @param buf 自定义字符串缓冲区
 * @param s 以/0结尾的传统字符串指针
 * @return 成功返回true，否则返回false
 */
static inline bool
sc_strbuf_append_str(struct sc_strbuf *buf, const char *s) {
    // const char *s 常量指针指向的值不能改变，但是这并不是意味着指针本身不能改变，常量指针可以指向其他的地址

    // strlen所作的是一个计数器的工作，它从内存的某个位置（可以是字符串开头，中间某个位置，甚至是某个不确定的内存区域）开始扫描，
    // 直到碰到第一个字符串结束符'\0'为止，然后返回计数器值(长度不包含'\0')    
    return sc_strbuf_append(buf, s, strlen(s));
}

/**
 * Append a static string
 *
 * Append a string whose size is known at compile time (for
 * example a string literal).
 */
#define sc_strbuf_append_staticstr(BUF, S) \
    sc_strbuf_append(BUF, S, sizeof(S) - 1)

/**
 * Shrink the buffer capacity to its current length 收缩字符串缓冲
 *
 * This resizes `buf->s` to fit the content.
 */
void
sc_strbuf_shrink(struct sc_strbuf *buf);

#endif
